package mdm.led.timeTask;

import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import mdm.led.dao.DopeMapper;
import mdm.led.dao.ThreeItemMapper;
import mdm.led.dao.ThreeTableMapper;
import mdm.led.dao.ThreeTaskSelfMapper;
import mdm.led.dao.UserMapper;
import mdm.led.entity.Dope;
import mdm.led.entity.User;
import mdm.led.entity.three.FindSelfCheckInspector;
import mdm.led.entity.three.FindThreeTaskSelf;
import mdm.led.entity.three.ThreeItem;
import mdm.led.entity.three.ThreeTable;
import mdm.led.entity.three.ThreeTaskSelf;

/**
 *
 * @author :Monarch丿He
 * @date :2018年11月16日
 * @explain :
 */
@Component
@Order(value = 2)
public class TaskApplicationRunner implements ApplicationRunner {

	private Logger logger = Logger.getLogger(TaskApplicationRunner.class);
	// 线程池
	private ScheduledExecutorService scheduExec;
	@Autowired
	private ThreeTableMapper threeTableDao;
	@Autowired
	private ThreeTaskSelfMapper taskSelfDao;
	@Autowired
	private ThreeItemMapper threeItemDao;
	@Autowired
	private ThreeTaskSelfMapper threeTaskSelfDao;
	@Autowired
	private DopeMapper dopeDao;
	@Autowired
	private UserMapper userDao;

	@Override
	public void run(ApplicationArguments args) throws Exception {
		// 启动三查周期检查生成检查表
		startCheck();
	}

	/**
	 * 构造方法
	 * 
	 * @throws Exception
	 */
	TaskApplicationRunner() throws Exception {
		this.scheduExec = Executors.newScheduledThreadPool(2);
	}

	/**
	 * 任务详情 三查周期生成表格 // 将近提醒
	 * 
	 * @throws Exception
	 */
	public void startCheck() throws Exception {

		// 延迟 指定时间 后 每隔 指定时间 执行指定任务
		scheduExec.scheduleAtFixedRate(new Runnable() {
			public void run() {
				logger.info("\n-- START -->> 执行定时任务  !\n");
				// 当前时间
				Date currentDate = new Date();

				try {
					// 实例化一个三查表实例 状态为 1: 有效
					ThreeTable table = new ThreeTable();
					table.setStatus(1);
					// 取到指令条件的所有三查表集合
					List<ThreeTable> findThreeTables = threeTableDao.findThreeTables(table);
					// 当前时间毫秒值
					long currentTime = new Date().getTime();
					// 循环遍历
					for (ThreeTable tableItem : findThreeTables) {
						Date date = null;
						// 表格周期 (天数)
						Integer period = tableItem.getPeriod();
						// 周期转化为毫秒值
						long periodMSEL = 86400000 * period;
						// 24 小时的 毫秒值
						long hourMSEL_24 = 86400000;
						// 表格修改时间
						Date updatetime = tableItem.getUpdatetime();
						// 如果修改时间为 空 则根据 开始时间计算
						date = (updatetime == null) ? (tableItem.getStarttime()) : (updatetime);
						// 获取表格的上一次创建时间的 毫秒值
						long time = date.getTime();
						// >>>将近提醒
						// 周期日期 + 上一次创建时间 小于 当前时间
						if (((time + periodMSEL - hourMSEL_24) <= currentTime) && (currentTime < (time + periodMSEL))) {
							FindThreeTaskSelf taskSelf = new FindThreeTaskSelf();
							// 将近提醒状态为 未提醒
							taskSelf.setAlmostTimeWarn(1);
							// 三查表ID
							taskSelf.setThreeID(tableItem.getThreeid());
							// 自查状态为未完成
							taskSelf.setState(1);
							// 获取当前表格下所有自查任务
							List<ThreeTaskSelf> findThreeTaskSelf = taskSelfDao.findThreeTaskSelf(taskSelf);
							ThreeTaskSelf self = new ThreeTaskSelf();
							for (ThreeTaskSelf item : findThreeTaskSelf) {
								// 消息实例
								Dope dope = new Dope();
								dope.setTime(currentDate);
								dope.setTitle("将近提醒");
								dope.setVisual(1);
								dope.setIfPop(1);
								dope.setPigment(1);
								dope.setType(1);
								dope.setStatus(2);
								dope.setContent("三查任务: " + item.getThreeName() + "\n 还有最后不到一天的检查时间!");
								dope.setReceiveMan(item.getSelfMan().toString());
								// 添加到数据库
								dopeDao.addAppointManDope(dope);

								self.setTaskID(item.getTaskID());
								self.setAlmostTimeWarn(2);
								taskSelfDao.updateThreeTaskSelf(self);

							}

						}

						// >>>超时提醒
						if ((time + periodMSEL) < currentTime) {
							FindThreeTaskSelf taskSelf = new FindThreeTaskSelf();
							// 将近提醒状态为 未提醒
							taskSelf.setAlmostTimeWarn(1);
							// 三查表ID
							taskSelf.setThreeID(tableItem.getThreeid());
							// 自查状态为未完成
							taskSelf.setState(1);
							// 获取当前表格下所有自查任务
							List<ThreeTaskSelf> findThreeTaskSelf = taskSelfDao.findThreeTaskSelf(taskSelf);
							ThreeTaskSelf self = new ThreeTaskSelf();
							for (ThreeTaskSelf item : findThreeTaskSelf) {
								// 消息实例
								Dope dope = new Dope();
								dope.setTime(currentDate);
								dope.setTitle("任务逾期");
								dope.setVisual(1);
								dope.setIfPop(1);
								dope.setPigment(1);
								dope.setType(1);
								dope.setStatus(2);
								User selectById = userDao.selectById(item.getSelfMan());
								dope.setContent("三查任务: " + item.getThreeName() + "\n 自查人 :" + selectById.getcNickname()
										+ "  \n未按规定时间完成 任务");
								dope.setReceiveMan(selectById.getcUserId().toString());
								// 发送到 自查人
								dopeDao.addAppointManDope(dope);
								// 自查人 检查人 抽查人
								FindSelfCheckInspector sci = userDao.findSelfCheckInspector(tableItem.getSelftype(),
										selectById.getcUserId());
								// 检查人
								Integer checkID = sci.getCheckID();
								if (checkID != null) {
									// 发送到检查人
									dope.setReceiveMan(checkID.toString());
									dopeDao.addAppointManDope(dope);
								}
								// 督查角色
								Integer inspectorID = sci.getInspectorID();
								if (inspectorID != null) {
									// 发送到督查角色
									dope.setReceiveMan(inspectorID.toString());
									dopeDao.addAppointManDope(dope);
								}

								self.setTaskID(item.getTaskID());
								self.setOverTimeWarn(2);
								taskSelfDao.updateThreeTaskSelf(self);

							}

						}

					}

				} catch (Exception e) {
					logger.info("\n=== 逾期提醒/超时提醒  >>> 出现异常===\n");
					e.printStackTrace();
				}

				// 1:根据周期生成新的自查表
				try {
					logger.info("\n>>>> start 根据周期生成新的自查表   <<<<\n");
					// 实例化一个三查表实例 状态为 1: 有效
					ThreeTable table = new ThreeTable();
					table.setStatus(1);
					// 取到指令条件的所有三查表集合
					List<ThreeTable> findThreeTables = threeTableDao.findThreeTables(table);
					// 当前时间毫秒值
					long currentTime = currentDate.getTime();
					// 循环遍历
					for (ThreeTable tableItem : findThreeTables) {
						// 判断 删选 start====
						// 表格周期 (天数)
						Integer period = tableItem.getPeriod();
						// 周期转化为毫秒值
						long periodMSEL = 86400000 * period;
						// 表格修改时间
						Date updatetime = tableItem.getUpdatetime();
						// 如果修改时间为 空 则根据 开始时间计算
						Date date = (updatetime == null) ? (tableItem.getStarttime()) : (updatetime);
						// 获取表格的上一次创建时间的 毫秒值
						long time = date.getTime();
						if (currentTime < (time + periodMSEL)) {
							continue;
						}
						// end===

						// 查询表格小所有检查项==
						ThreeItem threeItem = new ThreeItem();
						threeItem.setThreeid(tableItem.getThreeid());
						// 三查表对应检查项
						List<ThreeItem> items = threeItemDao.findThreeItem(threeItem);
						// 查询表格下自查任务==
						FindThreeTaskSelf taskSelf = new FindThreeTaskSelf();
						taskSelf.setThreeID(tableItem.getThreeid());
						// 获取当前表格下所有自查任务
						List<ThreeTaskSelf> findThreeTaskSelf = taskSelfDao.findThreeTaskSelf(taskSelf);
						for (ThreeTaskSelf threeTaskSelf : findThreeTaskSelf) {
							// 循环自查用户 添加自查任务
							ThreeTaskSelf self = new ThreeTaskSelf();
							// 根据自查人
							Integer departmentId = threeTaskSelf.getDepartment();
							self.setDepartment(departmentId);
							self.setThreeID(threeTaskSelf.getThreeID());
							self.setSelfMan(threeTaskSelf.getSelfMan());
							// 添加自查任务
							Integer addThreeTaskSelf = threeTaskSelfDao.addThreeTaskSelf(self);
							if (addThreeTaskSelf > 0) {
								for (ThreeItem item2 : items) {
									item2.setThreeid(null);
									item2.setDetailsid(self.getTaskID());
									// 添加自查任务检查项
									threeItemDao.addThreeItem(item2);
								}
							}
						}
						ThreeTable threeTable = new ThreeTable();
						threeTable.setUpdatetime(currentDate);
						threeTable.setThreeid(tableItem.getThreeid());
						threeTableDao.updateThreeTable(threeTable);

					}
					logger.info("\n>>>> end 根据周期生成新的自查表   <<<<\n\n");
				} catch (Exception e) {
					logger.info("\n===根据周期生成新的自查表  >>> 出现异常===\n");
					e.printStackTrace();
				}

				logger.info("\n --- END --- \n");
			}
			// MINUTES 分钟 //SECONDS 秒 //HOURS 小时
		}, 0, 12, TimeUnit.HOURS);
	}

}
